﻿/*
 *  Author: Louis A. Leskoviansky
 *  Company: Artemis Solutions Group (http://www.artemis-solutions.com)
 */


using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Web;
using System.Web.Configuration;

namespace AjaxControlFramework
{
    public static class RuntimeConfigUtils
    {
        //------// Properties \\--------------------------------------------\\
        private static Type RuntimeConfigType = Type.GetType("System.Web.Configuration.RuntimeConfig, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", true);


        private static object _runtimeConfig = null;
        private static object RuntimeConfig
        {
            get
            {
                if (_runtimeConfig == null)
                {
                    MethodInfo getConfigMethodInfo = RuntimeConfigType.GetMethod("GetClientRuntimeConfig", BindingFlags.Static | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
                    _runtimeConfig = getConfigMethodInfo.Invoke(null, new object[0]);
                }

                return _runtimeConfig;
            }
        }


        private delegate HttpHandlersSection HttpHandlersProperty(object runtimeConfig);

        private static HttpHandlersProperty _httpHandlers = null;
        private static HttpHandlersProperty HttpHandlers
        {
            get
            {
                if (_httpHandlers == null)
                {
                    PropertyInfo httpHandlersProperty = RuntimeConfigType.GetProperty("HttpHandlers", BindingFlags.Instance | BindingFlags.NonPublic, null, typeof(System.Web.Configuration.HttpHandlersSection), Type.EmptyTypes, null);
                    MethodInfo httpHandlersGetMethodInfo = httpHandlersProperty.GetGetMethod(true);

                    DynamicMethod httpHandlersMethod = new DynamicMethod("HttpHandlers", typeof(HttpHandlersSection), new Type[] { RuntimeConfigType }, true);

                    ILGenerator ilGenerator = httpHandlersMethod.GetILGenerator();
                    ilGenerator.Emit(OpCodes.Ldarg_0);
                    ilGenerator.Emit(OpCodes.Call, httpHandlersGetMethodInfo);
                    ilGenerator.Emit(OpCodes.Ret);

                    _httpHandlers = (HttpHandlersProperty)httpHandlersMethod.CreateDelegate(typeof(HttpHandlersProperty));
                }

                return _httpHandlers;
            }
        }
        //------\\ Properties //--------------------------------------------//



        //------// Methods \\-----------------------------------------------\\
        public static void AddHttpHandler(string path, string verb, string handlerType)
        {
            Type type = System.Web.Compilation.BuildManager.GetType(handlerType, true);

            if (type != null && !type.IsAssignableFrom(typeof(System.Web.IHttpHandler)))
            {
                throw new ArgumentException("The Type provided must derive from " + typeof(System.Web.IHttpHandler).FullName + ".", "handlerType");
            }

            HttpHandlers(RuntimeConfig).Handlers.Add(new HttpHandlerAction(path, type.AssemblyQualifiedName, verb));
        }
        //------\\ Methods //-----------------------------------------------//
    }
}
